#include "printSyntacticTree.h"
#include <string.h>

int indexExpr = 0;
int indexExprList = 0;
int indexStmt = 0;
int indexStmtList = 0;
int indexFuncDef = 0;
int indexTypeSpec = 0;
int indexVarDec = 0;
int indexVarDecList = 0;
int indexSet = 0;
int indexSetList = 0;
int indexArrayList = 0;
int indexOptionList = 0;
int indexLabelListOptions = 0;
int indexIfStmtCondition = 0;
int indexFuncStmtList = 0;

void tree_print(char* name)
{
	int curSetList, curVarDecList, curFuncStmtList;
	char buffer[20];
	char* str;
	treeFile = fopen(name, "w");

	fwrite("digraph Tree {\n", 15, 1, treeFile);

	if (root->vars)
	{		
		indexVarDecList++;
		curVarDecList = indexVarDecList;

		fwrite("\"root ", 6, 1, treeFile);
		fwrite(root->Id, strlen(root->Id), 1, treeFile);
		fwrite("\" -> varDecList", 15, 1, treeFile);
		str = itoa(curVarDecList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(";\n", 2, 1, treeFile);

		print_vardeclist(root->vars);
	}
	if (root->funcs)
	{
		indexFuncStmtList++;
		curFuncStmtList = indexFuncStmtList;

		fwrite("\"root ", 6, 1, treeFile);
		fwrite(root->Id, strlen(root->Id), 1, treeFile);
		fwrite("\" -> funcStmtList", 17, 1, treeFile);
		str = itoa(curFuncStmtList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(";\n", 2, 1, treeFile);

		print_funcstmtlist(root->funcs);
	}

	fwrite("}", 1, 1, treeFile);
	fclose(treeFile);
}
void print_expr(struct StExpr* node)
{
	int curIndexExpr;
	int curIndexExprLeft, curIndexExprRight, curIndexExprList, curIndexSet;
	char buffer[20];
	char* str;
	
	curIndexExpr = indexExpr;

	if (node->set)
	{
		indexSet++;
		curIndexSet = indexSet;

		if (node->set->startConstInt && node->set->finishConstInt)
		{
			fwrite("\"expr", 5, 1, treeFile);
			str = itoa(curIndexExpr, buffer, 10);
			fwrite(str, strlen(str), 1, treeFile);
			fwrite(" ", 1, 1, treeFile);
			strcpy(str,determineID(node));
			fwrite(str, strlen(str), 1, treeFile);
			fwrite(" ", 1, 1, treeFile);
			str = determineType(node->typeSpec);
			fwrite(str, strlen(str), 1, treeFile);
			str = determineArray(node->typeSpec);
			fwrite(str, strlen(str), 1, treeFile);
			fwrite("\" -> \"set ", 10, 1, treeFile);
			str = itoa(node->set->startConstInt, buffer, 10);
			fwrite(str, strlen(str), 1, treeFile);
			fwrite("..", 2, 1, treeFile);
			str = itoa(node->set->finishConstInt, buffer, 10);
			fwrite(str, strlen(str), 1, treeFile);
			fwrite("\";\n", 3, 1, treeFile);
		}
		if (node->set->startId && node->set->finishId)
		{
			fwrite("\"expr", 5, 1, treeFile);
			str = itoa(curIndexExpr, buffer, 10);
			fwrite(str, strlen(str), 1, treeFile);
			fwrite(" ", 1, 1, treeFile);
			strcpy(str,determineID(node));
			fwrite(str, strlen(str), 1, treeFile);
			fwrite(" ", 1, 1, treeFile);
			str = determineType(node->typeSpec);
			fwrite(str, strlen(str), 1, treeFile);
			str = determineArray(node->typeSpec);
			fwrite(str, strlen(str), 1, treeFile);
			fwrite("\" -> \"set ", 10, 1, treeFile);
			fwrite(node->set->startId, strlen(node->set->startId), 1, treeFile);
			fwrite("..", 2, 1, treeFile);
			fwrite(node->set->finishId, strlen(node->set->finishId), 1, treeFile);
			fwrite("\";\n", 3, 1, treeFile);
		}
		if (node->set->list)
		{
			fwrite("\"expr", 5, 1, treeFile);
			str = itoa(curIndexExpr, buffer, 10);
			fwrite(str, strlen(str), 1, treeFile);
			fwrite(" ", 1, 1, treeFile);
			strcpy(str,determineID(node));
			fwrite(str, strlen(str), 1, treeFile);
			fwrite(" ", 1, 1, treeFile);
			str = determineType(node->typeSpec);
			fwrite(str, strlen(str), 1, treeFile);
			str = determineArray(node->typeSpec);
			fwrite(str, strlen(str), 1, treeFile);
			fwrite("\" -> set", 8, 1, treeFile);
			str = itoa(curIndexSet, buffer, 10);
			fwrite(str, strlen(str), 1, treeFile);

			print_set(node->set);
		}
	}
	else if (node->left)
	{
		if (node->left->set)
		{
			indexSet++;
			curIndexSet = indexSet;

			if (node->left->set->startConstInt && node->left->set->finishConstInt)
			{
				fwrite("\"expr", 5, 1, treeFile);
				str = itoa(curIndexExpr, buffer, 10);
				fwrite(str, strlen(str), 1, treeFile);
				fwrite(" ", 1, 1, treeFile);
				strcpy(str,determineID(node));
				fwrite(str, strlen(str), 1, treeFile);
				fwrite(" ", 1, 1, treeFile);
				str = determineType(node->typeSpec);
				fwrite(str, strlen(str), 1, treeFile);
				str = determineArray(node->typeSpec);
				fwrite(str, strlen(str), 1, treeFile);
				fwrite("\" -> \"set ", 10, 1, treeFile);
				str = itoa(node->left->set->startConstInt, buffer, 10);
				fwrite(str, strlen(str), 1, treeFile);
				fwrite("..", 2, 1, treeFile);
				str = itoa(node->left->set->finishConstInt, buffer, 10);
				fwrite(str, strlen(str), 1, treeFile);
				fwrite("\";\n", 3, 1, treeFile);
			}
			if (node->left->set->startId && node->left->set->finishId)
			{
				fwrite("\"expr", 5, 1, treeFile);
				str = itoa(curIndexExpr, buffer, 10);
				fwrite(str, strlen(str), 1, treeFile);
				fwrite(" ", 1, 1, treeFile);
				strcpy(str,determineID(node));
				fwrite(str, strlen(str), 1, treeFile);
				fwrite(" ", 1, 1, treeFile);
				str = determineType(node->typeSpec);
				fwrite(str, strlen(str), 1, treeFile);
				str = determineArray(node->typeSpec);
				fwrite(str, strlen(str), 1, treeFile);
				fwrite("\" -> \"set ", 10, 1, treeFile);
				fwrite(node->left->set->startId, strlen(node->left->set->startId), 1, treeFile);
				fwrite("..", 2, 1, treeFile);
				fwrite(node->left->set->finishId, strlen(node->left->set->finishId), 1, treeFile);
				fwrite("\";\n", 3, 1, treeFile);
			}
			if (node->left->set->list)
			{
				fwrite("\"expr", 5, 1, treeFile);
				str = itoa(curIndexExpr, buffer, 10);
				fwrite(str, strlen(str), 1, treeFile);
				fwrite(" ", 1, 1, treeFile);
				strcpy(str,determineID(node));
				fwrite(str, strlen(str), 1, treeFile);
				fwrite(" ", 1, 1, treeFile);
				str = determineType(node->typeSpec);
				fwrite(str, strlen(str), 1, treeFile);
				str = determineArray(node->typeSpec);
				fwrite(str, strlen(str), 1, treeFile);
				fwrite("\" -> set", 8, 1, treeFile);
				str = itoa(curIndexSet, buffer, 10);
				fwrite(str, strlen(str), 1, treeFile);
				fwrite(";\n", 2, 1, treeFile);

				print_set(node->left->set);
			}
		}
		else
		{
			indexExpr++;
			curIndexExprLeft = indexExpr;

			fwrite("\"expr", 5, 1, treeFile);
			str = itoa(curIndexExpr, buffer, 10);
			fwrite(str, strlen(str), 1, treeFile);
			fwrite(" ", 1, 1, treeFile);
			strcpy(str,determineID(node));
			fwrite(str, strlen(str), 1, treeFile);
			fwrite(" ", 1, 1, treeFile);
			str = determineType(node->typeSpec);
			fwrite(str, strlen(str), 1, treeFile);
			str = determineArray(node->typeSpec);
			fwrite(str, strlen(str), 1, treeFile);
			fwrite("\" -> \"expr", 10, 1, treeFile);
			str = itoa(curIndexExprLeft, buffer, 10);
			fwrite(str, strlen(str), 1, treeFile);
			fwrite(" ", 1, 1, treeFile);
			strcpy(str,determineID(node->left));
			fwrite(str, strlen(str), 1, treeFile);
			fwrite(" ", 1, 1, treeFile);
			str = determineType(node->left->typeSpec);
			fwrite(str, strlen(str), 1, treeFile);
			str = determineArray(node->left->typeSpec);
			fwrite(str, strlen(str), 1, treeFile);
			fwrite("\";\n", 3, 1, treeFile);

			print_expr(node->left);
		}
	}
	if (node->right)
	{
		if (node->right->set)
		{
			indexSet++;
			curIndexSet = indexSet;

			if (node->right->set->startConstInt && node->right->set->finishConstInt)
			{
				fwrite("\"expr", 5, 1, treeFile);
				str = itoa(curIndexExpr, buffer, 10);
				fwrite(str, strlen(str), 1, treeFile);
				fwrite(" ", 1, 1, treeFile);
				strcpy(str,determineID(node));
				fwrite(str, strlen(str), 1, treeFile);
				fwrite(" ", 1, 1, treeFile);
				str = determineType(node->typeSpec);
				fwrite(str, strlen(str), 1, treeFile);
				str = determineArray(node->typeSpec);
				fwrite(str, strlen(str), 1, treeFile);
				fwrite("\" -> \"set ", 10, 1, treeFile);
				str = itoa(node->right->set->startConstInt, buffer, 10);
				fwrite(str, strlen(str), 1, treeFile);
				fwrite("..", 2, 1, treeFile);
				str = itoa(node->right->set->finishConstInt, buffer, 10);
				fwrite(str, strlen(str), 1, treeFile);
				fwrite("\";\n", 3, 1, treeFile);
			}
			if (node->right->set->startId && node->right->set->finishId)
			{
				fwrite("\"expr", 5, 1, treeFile);
				str = itoa(curIndexExpr, buffer, 10);
				fwrite(str, strlen(str), 1, treeFile);
				fwrite(" ", 1, 1, treeFile);
				strcpy(str,determineID(node));
				fwrite(str, strlen(str), 1, treeFile);
				fwrite(" ", 1, 1, treeFile);
				str = determineType(node->typeSpec);
				fwrite(str, strlen(str), 1, treeFile);
				str = determineArray(node->typeSpec);
				fwrite(str, strlen(str), 1, treeFile);
				fwrite("\" -> \"set ", 10, 1, treeFile);
				fwrite(node->right->set->startId, strlen(node->right->set->startId), 1, treeFile);
				fwrite("..", 2, 1, treeFile);
				fwrite(node->right->set->finishId, strlen(node->right->set->finishId), 1, treeFile);
				fwrite("\";\n", 3, 1, treeFile);
			}
			if (node->right->set->list)
			{
				fwrite("\"expr", 5, 1, treeFile);
				str = itoa(curIndexExpr, buffer, 10);
				fwrite(str, strlen(str), 1, treeFile);
				fwrite(" ", 1, 1, treeFile);
				strcpy(str,determineID(node));
				fwrite(str, strlen(str), 1, treeFile);
				fwrite(" ", 1, 1, treeFile);
				str = determineType(node->typeSpec);
				fwrite(str, strlen(str), 1, treeFile);
				str = determineArray(node->typeSpec);
				fwrite(str, strlen(str), 1, treeFile);
				fwrite("\" -> set", 8, 1, treeFile);
				str = itoa(curIndexSet, buffer, 10);
				fwrite(str, strlen(str), 1, treeFile);
				fwrite(";\n", 2, 1, treeFile);

				print_set(node->right->set);
			}
		}
		else
		{
			indexExpr++;
			curIndexExprRight = indexExpr;

			fwrite("\"expr", 5, 1, treeFile);
			str = itoa(curIndexExpr, buffer, 10);
			fwrite(str, strlen(str), 1, treeFile);
			fwrite(" ", 1, 1, treeFile);
			strcpy(str,determineID(node));
			fwrite(str, strlen(str), 1, treeFile);
			fwrite(" ", 1, 1, treeFile);
			str = determineType(node->typeSpec);
			fwrite(str, strlen(str), 1, treeFile);			
			str = determineArray(node->typeSpec);
			fwrite(str, strlen(str), 1, treeFile);
			fwrite("\" -> \"expr", 10, 1, treeFile);
			str = itoa(curIndexExprRight, buffer, 10);
			fwrite(str, strlen(str), 1, treeFile);
			fwrite(" ", 1, 1, treeFile);
			strcpy(str,determineID(node->right));
			fwrite(str, strlen(str), 1, treeFile);
			fwrite(" ", 1, 1, treeFile);
			str = determineType(node->right->typeSpec);
			fwrite(str, strlen(str), 1, treeFile);			
			str = determineArray(node->right->typeSpec);
			fwrite(str, strlen(str), 1, treeFile);
			fwrite("\";\n", 3, 1, treeFile);

			print_expr(node->right);	
		}
	}
	if (node->list)
	{
		indexExprList++;
		curIndexExprList = indexExprList;

		fwrite("\"expr", 5, 1, treeFile);
		str = itoa(curIndexExpr, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		strcpy(str,determineID(node));
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		str = determineType(node->typeSpec);
		fwrite(str, strlen(str), 1, treeFile);
		str = determineArray(node->typeSpec);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite("\" -> exprList", 13, 1, treeFile);
		str = itoa(curIndexExprList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(";\n", 2, 1, treeFile);

		print_exprlist(node->list);
	}	
	if (node->indexArray)
	{
		indexExpr++;
		curIndexExprRight = indexExpr;

		fwrite("\"expr", 5, 1, treeFile);
		str = itoa(curIndexExpr, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		strcpy(str,determineID(node));
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		str = determineType(node->typeSpec);
		fwrite(str, strlen(str), 1, treeFile);			
		str = determineArray(node->typeSpec);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite("\" -> \"expr", 10, 1, treeFile);
		str = itoa(curIndexExprRight, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		strcpy(str,determineID(node->indexArray));
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		str = determineType(node->indexArray->typeSpec);
		fwrite(str, strlen(str), 1, treeFile);			
		str = determineArray(node->indexArray->typeSpec);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite("\";\n", 3, 1, treeFile);

		print_expr(node->indexArray);
	}
}

void print_exprlist(struct StExprList* node)
{
	char* str;
	char buffer[20];
	int curIndexExpr, curIndexExprListNext;
	int curIndexExprList;
	
	curIndexExprList = indexExprList;

	if (node->current)
	{
		indexExpr++;
		curIndexExpr = indexExpr;

		fwrite("exprList", 8, 1, treeFile);
		str = itoa(curIndexExprList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" -> \"expr", 9, 1, treeFile);
		str = itoa(curIndexExpr, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		strcpy(str,determineID(node->current));
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		str = determineType(node->current->typeSpec);
		fwrite(str, strlen(str), 1, treeFile);
		str = determineArray(node->current->typeSpec);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite("\";\n", 3, 1, treeFile);

		print_expr(node->current);
	}
	if (node->next)
	{
		indexExprList++;
		curIndexExprListNext = indexExprList;

		fwrite("exprList", 8, 1, treeFile);
		str = itoa(curIndexExprList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" -> exprList", 12, 1, treeFile);
		str = itoa(curIndexExprListNext, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(";\n", 2, 1, treeFile);

		print_exprlist(node->next);
	}
}

void print_stmt(struct StStmt* node)
{
	int curIndexExpr1, curIndexExpr2, curIndexStmtList, curIndexOption_list, curIndexIfStmtCondition;
	char* str;
	char buffer[20];
	int curStmt;

	curStmt = indexStmt;

	if (node->expr)
	{
		indexExpr++;
		curIndexExpr1 = indexExpr;

		fwrite("\"stmt", 5, 1, treeFile);
		str = itoa(curStmt, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		str = determineStmr(node);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite("\" -> \"expr", 10, 1, treeFile);
		str = itoa(curIndexExpr1, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		strcpy(str,determineID(node->expr));
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		str = determineType(node->expr->typeSpec);
		fwrite(str, strlen(str), 1, treeFile);
		str = determineArray(node->expr->typeSpec);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite("\";\n", 3, 1, treeFile);

		print_expr(node->expr);
	}
	if (node->exprForEdn)
	{
		indexExpr++;
		curIndexExpr2 = indexExpr;

		fwrite("\"stmt", 5, 1, treeFile);
		str = itoa(curStmt, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		str = determineStmr(node);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite("\" -> \"expr", 10, 1, treeFile);
		str = itoa(curIndexExpr2, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		strcpy(str,determineID(node->exprForEdn));
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		str = determineType(node->exprForEdn->typeSpec);
		fwrite(str, strlen(str), 1, treeFile);
		str = determineArray(node->exprForEdn->typeSpec);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite("\";\n", 3, 1, treeFile);

		print_expr(node->exprForEdn);
	}
	if (node->stmtList)
	{
		indexStmtList++;
		curIndexStmtList = indexStmtList;

		fwrite("\"stmt", 5, 1, treeFile);
		str = itoa(curStmt, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		str = determineStmr(node);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite("\" -> stmtList", 13, 1, treeFile);
		str = itoa(curIndexStmtList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(";\n", 2, 1, treeFile);

		print_stmtlist(node->stmtList);
	}
	if (node->option_list)
	{
		indexOptionList++;
		curIndexOption_list = indexOptionList;

		fwrite("\"stmt", 5, 1, treeFile);
		str = itoa(curStmt, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		str = determineStmr(node);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite("\" -> optionList", 15, 1, treeFile);
		str = itoa(curIndexOption_list, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(";\n", 2, 1, treeFile);

		print_optionlist(node->option_list);
	}
	if (node->ifStmtCondition)
	{
		indexIfStmtCondition++;
		curIndexIfStmtCondition = indexIfStmtCondition;

		fwrite("\"stmt", 5, 1, treeFile);
		str = itoa(curStmt, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		str = determineStmr(node);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite("\" -> ifStmtCondition", 20, 1, treeFile);
		str = itoa(curIndexIfStmtCondition, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(";\n", 2, 1, treeFile);

		print_ifstmtcondition(node->ifStmtCondition);
	}
}

void print_stmtlist(struct StStmtList* node)
{
	int currentIndexStmtList, curStStmt, curStStmtList;
	char* str;
	char buffer[20];

	currentIndexStmtList = indexStmtList;

	if (node->current)
	{
		indexStmt++;
		curStStmt = indexStmt;

		fwrite("stmtList", 8, 1, treeFile);
		str = itoa(currentIndexStmtList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" -> \"stmt", 9, 1, treeFile);
		str = itoa(curStStmt, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		str = determineStmr(node->current);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite("\";\n", 3, 1, treeFile);

		print_stmt(node->current);
	}
	if (node->next)
	{
		indexStmtList++;
		curStStmtList = indexStmtList;

		fwrite("stmtList", 8, 1, treeFile);
		str = itoa(currentIndexStmtList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" -> stmtList", 12, 1, treeFile);
		str = itoa(curStStmtList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(";\n", 2, 1, treeFile);

		print_stmtlist(node->next);
	}
}

void print_funcdec(struct StFuncDef* node)
{
	int curIndexVarDecList, curIndexFuncDef, curIndexTypeSpec, curStStmtList;
	char* str;
	char buffer[20];

	curIndexFuncDef = indexFuncDef;

	if (node->parameter_list)
	{
		indexVarDecList++;
		curIndexVarDecList = indexVarDecList;

		fwrite("\"func", 5, 1, treeFile);
		str = itoa(curIndexFuncDef, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		fwrite(node->nameFunc, strlen(node->nameFunc), 1, treeFile);
		fwrite("\" -> varDecList", 15, 1, treeFile);
		str = itoa(curIndexVarDecList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(";\n", 2, 1, treeFile);

		print_vardeclist(node->parameter_list);
	}
	if (node->type)
	{
		indexTypeSpec++;
		curIndexTypeSpec = indexTypeSpec;

		fwrite("\"func", 5, 1, treeFile);
		str = itoa(curIndexFuncDef, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		fwrite(node->nameFunc, strlen(node->nameFunc), 1, treeFile);
		fwrite("\" -> \"typeSpec", 14, 1, treeFile);
		str = itoa(curIndexTypeSpec, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		str = determineType(node->type);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite("\";\n", 3, 1, treeFile);

		print_typespec(node->type);
	}
	if (node->var_declaration_list)
	{
		indexVarDecList++;
		curIndexVarDecList = indexVarDecList;

		fwrite("\"func", 5, 1, treeFile);
		str = itoa(curIndexFuncDef, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		fwrite(node->nameFunc, strlen(node->nameFunc), 1, treeFile);
		fwrite("\" -> varDecList", 15, 1, treeFile);
		str = itoa(curIndexVarDecList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(";\n", 2, 1, treeFile);

		print_vardeclist(node->var_declaration_list);
	}
	if (node->stmtList)
	{
		indexStmtList++;
		curStStmtList = indexStmtList;

		fwrite("\"func", 5, 1, treeFile);
		str = itoa(curIndexFuncDef, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		fwrite(node->nameFunc, strlen(node->nameFunc), 1, treeFile);
		fwrite("\" -> stmtList", 13, 1, treeFile);
		str = itoa(curStStmtList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(";\n", 2, 1, treeFile);

		print_stmtlist(node->stmtList);
	}
}

void print_typespec(struct StTypeSpec* node)
{
	int curIndexTypeSpec, curIndexArrayList;
	char* str;
	char buffer[20];
	char* result;

	curIndexTypeSpec = indexTypeSpec;

	if (node->_array)
	{
		indexArrayList++;
		curIndexArrayList = indexArrayList;

		fwrite("\"typeSpec", 9, 1, treeFile);
		str = itoa(curIndexTypeSpec, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		str = determineType(node);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite("\" -> arrayList", 14, 1, treeFile);
		str = itoa(curIndexArrayList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(";\n", 2, 1, treeFile);

		print_arraylist(node->_array);
	}
}

void print_vardec(struct StVarDec* node)
{
	int curIndexVarDec, curIndexSetList, curIndexTypeSpec;
	char* str;
	char buffer[20];

	curIndexVarDec = indexVarDec;

	if (node->list)
	{
		indexSetList++;
		curIndexSetList = indexSetList;

		fwrite("varDec", 6, 1, treeFile);
		str = itoa(curIndexVarDec, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" -> \"setList", 12, 1, treeFile);
		str = itoa(curIndexSetList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		fwrite(node->list->currentId, strlen(node->list->currentId), 1, treeFile);
		fwrite("\";\n", 3, 1, treeFile);

		print_setlist(node->list);
	}
	if (node->type)
	{
		indexTypeSpec++;
		curIndexTypeSpec = indexTypeSpec;

		fwrite("varDec", 6, 1, treeFile);
		str = itoa(curIndexVarDec, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" -> \"typeSpec", 13, 1, treeFile);
		str = itoa(curIndexTypeSpec, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		str = determineType(node->type);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite("\";\n", 3, 1, treeFile);

		print_typespec(node->type);
	}
}

void print_vardeclist(struct StVarDecList* node)
{
	char* str;
	char buffer[20];
	int curIndexVarDecList, curIndexVarDecListNext, curIndexVarDec;

	curIndexVarDecList =  indexVarDecList;

	if (node->current)
	{
		indexVarDec++;
		curIndexVarDec = indexVarDec;

		fwrite("varDecList", 10, 1, treeFile);
		str = itoa(curIndexVarDecList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" -> varDec", 10, 1, treeFile);
		str = itoa(curIndexVarDec, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(";\n", 2, 1, treeFile);

		print_vardec(node->current);
	}
	if (node->next)
	{
		indexVarDecList++;
		curIndexVarDecListNext = indexVarDecList;

		fwrite("varDecList", 10, 1, treeFile);
		str = itoa(curIndexVarDecList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" -> varDecList", 14, 1, treeFile);
		str = itoa(curIndexVarDecListNext, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(";\n", 2, 1, treeFile);

		print_vardeclist(node->next);
	}
}

void print_set(struct StSet* node)
{
	char* str;
	char buffer[20];
	int curIndexSet, curIndexSetList;

	curIndexSet = indexSet;

	if (node->list)
	{
		indexSetList++;
		curIndexSetList = indexSetList;

		fwrite("set", 3, 1, treeFile);
		str = itoa(curIndexSet, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" -> \"setList", 12, 1, treeFile);
		str = itoa(curIndexSetList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		if (node->list->currentId)
		{
			fwrite(node->list->currentId, strlen(node->list->currentId), 1, treeFile);
		}
		else if (node->list->currentInt)
		{
			str = itoa(node->list->currentInt, buffer, 10);
			fwrite(str, strlen(str), 1, treeFile);
		}
		fwrite("\";\n", 3, 1, treeFile);

		print_setlist(node->list);
	}
}

void print_setlist(struct StSetList* node)
{
	int curIndexSetList, curIndexSetListNext;
	char* str;
	char buffer[20];

	curIndexSetList = indexSetList;

	if (node->next)
	{
		indexSetList++;
		curIndexSetListNext = indexSetList;

		fwrite("\"setList", 8, 1, treeFile);
		str = itoa(curIndexSetList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		if (node->currentId)
		{
			fwrite(node->currentId, strlen(node->currentId), 1, treeFile);
		}
		else if (node->currentInt)
		{
			str = itoa(node->currentInt, buffer, 10);
			fwrite(str, strlen(str), 1, treeFile);
		}
		fwrite("\" -> \"setList", 13, 1, treeFile);
		str = itoa(curIndexSetListNext, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		if (node->next->currentId)
		{
			fwrite(node->next->currentId, strlen(node->next->currentId), 1, treeFile);
		}
		else if (node->next->currentInt)
		{
			str = itoa(node->next->currentInt, buffer, 10);
			fwrite(str, strlen(str), 1, treeFile);
		}
		fwrite("\";\n", 3, 1, treeFile);

		print_setlist(node->next);
	}
}

void print_arraylist(struct StArrayList* node)
{
	char* str;
	char buffer[20];
	int curIndexSetList, curIndexArrayList, curIndexArrayListNext;

	curIndexArrayList = indexArrayList;

	if (node->list)
	{
		indexSetList++;
		curIndexSetList = indexSetList;

		fwrite("arrayList", 9, 1, treeFile);
		str = itoa(curIndexArrayList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" -> \"setList", 12, 1, treeFile);
		str = itoa(curIndexSetList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		if (node->list->currentId)
		{
			fwrite(node->list->currentId, strlen(node->list->currentId), 1, treeFile);
		}
		else if (node->list->currentInt)
		{
			str = itoa(node->list->currentInt, buffer, 10);
			fwrite(str, strlen(str), 1, treeFile);
		}
		fwrite("\";\n", 3, 1, treeFile);

		print_setlist(node->list);
	}
	/*if (node->next)
	{
		indexArrayList++;
		curIndexArrayListNext = indexArrayList;

		fwrite("arrayList", 9, 1, treeFile);
		str = itoa(curIndexArrayList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" -> arrayList", 13, 1, treeFile);
		str = itoa(curIndexArrayList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(";\n", 2, 1, treeFile);

		print_arraylist(node->next);
	}*/
}

void print_optionlist(struct StOptionList* node)
{
	char* str;
	char buffer[20];
	int curIndexOptionList, curIndexLabelListOptions, curIndexStmtList, curIndexOptionListNext;

	curIndexOptionList = indexOptionList;

	if (node->listOptions)
	{
		indexLabelListOptions++;
		curIndexLabelListOptions = indexLabelListOptions;

		fwrite("optionList", 10, 1, treeFile);
		str = itoa(curIndexOptionList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" -> \"labelListOptions", 21, 1, treeFile);
		str = itoa(curIndexLabelListOptions, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		fwrite(node->listOptions->start, strlen(node->listOptions->start), 1, treeFile);
		if (node->listOptions->finish)
		{
			fwrite("..", 2, 1, treeFile);
			fwrite(node->listOptions->finish, strlen(node->listOptions->finish), 1, treeFile);
		}
		fwrite("\";\n", 3, 1, treeFile);

		print_labellistoptions(node->listOptions);
	}
	if (node->StmtList)
	{
		indexStmtList++;
		curIndexStmtList = indexStmtList;

		fwrite("optionList", 10, 1, treeFile);
		str = itoa(curIndexOptionList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" -> stmtList", 12, 1, treeFile);
		str = itoa(curIndexStmtList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(";\n", 2, 1, treeFile);

		print_stmtlist(node->StmtList);
	}
	if (node->next)
	{
		indexOptionList++;
		curIndexOptionListNext = indexOptionList;

		fwrite("optionList", 10, 1, treeFile);
		str = itoa(curIndexOptionList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" -> optionList", 14, 1, treeFile);
		str = itoa(curIndexOptionListNext, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(";\n", 2, 1, treeFile);

		print_optionlist(node->next);
	}
}

void print_labellistoptions(struct StLabelListOptions* node)
{
	char* str;
	char buffer[20];
	int curIndexLabelListOptions, curIndexLabelListOptionsNext;

	curIndexLabelListOptions = indexLabelListOptions;

	if (node->next)
	{
		indexLabelListOptions++;
		curIndexLabelListOptionsNext = indexLabelListOptions;

		fwrite("\"labelListOptions", 17, 1, treeFile);
		str = itoa(curIndexLabelListOptions, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		fwrite(node->start, strlen(node->start), 1, treeFile);
		if (node->finish)
		{
			fwrite("..", 2, 1, treeFile);
			fwrite(node->finish, strlen(node->finish), 1, treeFile);
		}
		fwrite("\" -> \"labelListOptions", 22, 1, treeFile);
		str = itoa(curIndexLabelListOptionsNext, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		fwrite(node->next->start, strlen(node->next->start), 1, treeFile);
		if (node->next->finish)
		{
			fwrite("..", 2, 1, treeFile);
			fwrite(node->next->finish, strlen(node->next->finish), 1, treeFile);
		}
		fwrite("\";\n", 3, 1, treeFile);

		print_labellistoptions(node->next);
	}
}

void print_ifstmtcondition(struct StIfStmtCondition* node)
{
	int curIndexIfStmtCondition, curIndexIfStmtConditionNext, curIndexExpr, curIndexStmtList;
	char* str;
	char buffer[20];

	curIndexIfStmtCondition = indexIfStmtCondition;

	if (node->expr)
	{
		indexExpr++;
		curIndexExpr = indexExpr;

		fwrite("ifStmtCondition", 15, 1, treeFile);
		str = itoa(curIndexIfStmtCondition, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" -> \"expr", 9, 1, treeFile);
		str = itoa(curIndexExpr, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		strcpy(str,determineID(node->expr));
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		str = determineType(node->expr->typeSpec);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite("\";\n", 3, 1, treeFile);

		print_expr(node->expr);
	}
	if (node->body)
	{
		indexStmtList++;
		curIndexStmtList = indexStmtList;

		fwrite("ifStmtCondition", 15, 1, treeFile);
		str = itoa(curIndexIfStmtCondition, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" -> stmtList", 12, 1, treeFile);
		str = itoa(curIndexStmtList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(";\n", 2, 1, treeFile);

		print_stmtlist(node->body);
	}
	if (node->next)
	{
		indexIfStmtCondition++;
		curIndexIfStmtConditionNext = indexIfStmtCondition;

		fwrite("ifStmtCondition", 15, 1, treeFile);
		str = itoa(curIndexIfStmtCondition, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" -> ifStmtCondition", 19, 1, treeFile);
		str = itoa(curIndexIfStmtConditionNext, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(";\n", 2, 1, treeFile);

		print_ifstmtcondition(node->next);
	}
}

void print_funcstmtlist(struct StFuncStmtList* node)
{
	int curIndexFuncStmtList, curIndexFuncStmtListNext, curIndexFuncDef;
	char* str;
	char buffer[20];

	curIndexFuncStmtList = indexFuncStmtList;

	if (node->current)
	{
		indexFuncDef++;
		curIndexFuncDef = indexFuncDef;

		fwrite("funcStmtList", 12, 1, treeFile);
		str = itoa(curIndexFuncStmtList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" -> \"func", 9, 1, treeFile);
		str = itoa(curIndexFuncDef, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" ", 1, 1, treeFile);
		fwrite(node->current->nameFunc, strlen(node->current->nameFunc), 1, treeFile);
		fwrite("\";\n", 3, 1, treeFile);

		print_funcdec(node->current);
	}
	if (node->next)
	{
		indexFuncStmtList++;
		curIndexFuncStmtListNext = indexFuncStmtList;

		fwrite("funcStmtList", 12, 1, treeFile);
		str = itoa(curIndexFuncStmtList, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(" -> funcStmtList", 16, 1, treeFile);
		str = itoa(curIndexFuncStmtListNext, buffer, 10);
		fwrite(str, strlen(str), 1, treeFile);
		fwrite(";\n", 2, 1, treeFile);

		print_funcstmtlist(node->next);
	}
}

char * determineType(struct StTypeSpec* node)
{
	switch (node->type)
	{
	case EBoolean:
		return "boolean";
	case EChar:
		return "char";
	case EInteger:
		return "int";
	case EReal:
		return "real";
	case ESet:
		return "set";
	case EString:
		return "string";
	case EArray:
		return "array";
	case EVoid:
		return "void";
	case ENull:
		return "null";
	}
	return NULL;
}

char * determineArray(struct StTypeSpec* node)
{
	struct StSetList * list = NULL;
	char* name = (char *)malloc(10);

	if (node->_array != NULL && node->_array != 0xcdcdcdcd)
	{
		list = node->_array->list;
		strcpy(name, "[\0");
		list = list->next;
	}
	else
		return "";

	while (list)
	{
		name = strcat(name, "[\0");
		list = list->next;
	}

	return name;
}

char* determineID(struct StExpr* node)
{
	char buffer[20];
	char* str  = (char *)malloc(sizeof(char)*100);

	if (node->Id)
		return node->Id;
	else if (node->type == EnInt)
		return itoa(node->constInt, buffer, 10);
	else if (node->type == EnReal)
	{
		sprintf(str,"%f",node->constReal);
		return str;
	}
	else if (node->type == EnSet)
	{
		if (node->set->startConstInt && node->set->finishConstInt)
		{
			strcpy(str, "set ");
			strcat(str, itoa(node->set->startConstInt, buffer, 10));
			strcat(str, " ");
			strcat(str, itoa(node->set->finishConstInt, buffer, 10));
		}
		if (node->set->startId && node->set->finishId)
		{
			strcpy(str, "set ");
			strcat(str, node->set->startId);
			strcat(str, " ");
			strcat(str, node->set->finishId);
		}
		if (node->set->list)
		{
			strcpy(str, "setList ");
			if (node->set->list->currentId)
				strcat(str, node->set->list->currentId);
			else
				strcat(str, itoa(node->set->list->currentInt, buffer, 10));
		}
		return str;
	}
	else
	{
		switch (node->type)
		{
		case EnPlus:
			return "+";
			break;
		case EnMinus:
			return "-";
			break;
		case EnMultiply:
			return "*";
			break;
		case EnDivision:
			return "/";
			break;
		case EnDiv:
			return "div";
			break;
		case EnMod:
			return "mod";
			break;
		case EnOr:
			return "or";
			break;
		case EnAnd:
			return "&";
			break;
		case EnNot:
			return "~";
			break;
		case EnAssignment:
			return ":=";
			break;
		case EnCompare:
			return "=";
			break;
		case EnNotCompare:
			return "#";
			break;
		case EnLess:
			return "<";
			break;
		case EnLessEqually:
			return "<=";
			break;
		case EnMore:
			return ">";
			break;
		case EnMoreEqually:
			return ">=";
			break;
		case EnUnMinus:
			return "-";
			break;
		case EnArrayAccess:
			return "[]";
			break;
		case EnSet:
			return "set";
			break;
		case EnFunc:
			return "func";
			break;
		case EnIn:
			return "in";
			break;
		case EnArrayAssign:
			return "[]=";
			break;
		case EnConvertType:
			return "ConverType";
			break;
		}
	}
	return NULL;
}

char* determineStmr(struct StStmt* node)
{
	switch (node->type)
	{
	case EnExpr:
		return "expr";
	case EnCase:
		return "case";
	case EnIf:
		return "if";
	case EnWhile:
		return "while";
	case EnRepeat:
		return "repeat";
	case EnFor:
		return "for";
	case EnLoop:
		return "loop";
	case EnReturn:
		return "return";
	case EnExit:
		return "exit";
	}
	return NULL;
}